<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Windows Controls I</title>
<link rel="stylesheet" href="/cfg/format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="Winapi, Windows API, Win32 API, C, conrols">
<meta name="description" content="In this part of the Windows API tutorial,
we will cover various Windows controls.">
<meta name="language" content="en">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">

<script type="text/javascript" src="/lib/jquery.js"></script>
<script type="text/javascript" src="/lib/common.js"></script>

</head>

<body>

<div class="container2">

<div id="wide_ad" class="ltow">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* 160x600, August 2011 */
google_ad_slot = "2484182563";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<div class="content2">


<a href="/" title="Home">Home</a>&nbsp;
<a href="..">Contents</a>


<h1>Windows controls I</h1>


<p>
Controls are basic building blocks of a windows application. Controls are 
called widgets in UNIX environment.
</p>

<div class="big_hor">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-9706709751191532";
/* big_horizontal */
google_ad_slot = "2904953388";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>


<h2>Static control</h2>

<p>
The static control displays text and graphics. The static control cannot be 
selected. It cannot have keyboard focus.
</p>


<pre class="code">
#include &lt;windows.h&gt;

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);


int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PWSTR lpCmdLine, int nCmdShow)
{
  MSG  msg;    
  WNDCLASSW wc = {0};
  wc.lpszClassName = L"Static Control";
  wc.hInstance     = hInstance;
  wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
  wc.lpfnWndProc   = WndProc;
  wc.hCursor       = LoadCursor(0,IDC_ARROW);

  
  RegisterClassW(&wc);
  CreateWindowW(wc.lpszClassName, L"Criminal",
                WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                100, 100, 330, 270, 0, 0, hInstance, 0);

  while( GetMessage(&msg, NULL, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }

  return (int) msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, 
    WPARAM wParam, LPARAM lParam)
{
  static wchar_t *lyrics =  L"I know you told me I should stay away\n\
I know you said he's just a dog astray\n\
He is a bad boy with a tainted heart\n\
And even I know this ain't smart\n\
\n\
But mama, I'm in love with a criminal\n\
And this type of love isn't rational, it's physical\n\
Mama, please don't cry, I will be alright\n\
All reason aside, I just can't deny, love the guy\n\
";

  switch(msg)  
  {
      case WM_CREATE:
      
        CreateWindowW(L"STATIC", lyrics, 
            WS_CHILD | WS_VISIBLE | SS_LEFT,
            20, 20, 300, 230,
            hwnd, (HMENU) 1, NULL, NULL);
        break;

      case WM_DESTROY:

        PostQuitMessage(0);
        break;
  }

  return DefWindowProcW(hwnd, msg, wParam, lParam);
}
</pre>

<p>
We show  lyrics of a song on a window.
</p>

<pre class="explanation">
CreateWindowW(L"STATIC", lyrics, 
    WS_CHILD | WS_VISIBLE | SS_LEFT,
    20, 20, 300, 230,
    hwnd, (HMENU) 1, NULL, NULL);
break;
</pre>

<p>
Here we create the static control. We display text. It is aligned 
to the left.
</p>

<img src="/img/gui/winapi/static.png" alt="Static control">
<div class="figure">Static control</div>



<h2>Button</h2>

<p>
A button is a simple control. It has a text label. It is used to 
trigger an action. When we click on a button, it sends a <code>WM_COMMAND</code>
message to its parent window. The low-order word of the <code>wParam</code>
parameter contains the control identifier. 
</p>


<pre class="code">
#include &lt;windows.h&gt;

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);


int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PWSTR lpCmdLine, int nCmdShow)
{
  MSG  msg;
  WNDCLASSW wc = {0};
  wc.lpszClassName = L"Buttons";
  wc.hInstance     = hInstance;
  wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
  wc.lpfnWndProc   = WndProc;
  wc.hCursor       = LoadCursor(0, IDC_ARROW);

  RegisterClassW(&wc);
  CreateWindowW(wc.lpszClassName, L"Buttons",
                WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                150, 150, 230, 150, 0, 0, hInstance, 0);

  while( GetMessage(&msg, NULL, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }

  return (int) msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, 
    WPARAM wParam, LPARAM lParam)
{    
  switch(msg)  
  {
    case WM_CREATE:

      CreateWindowW(L"button", L"Beep",
          WS_VISIBLE | WS_CHILD ,
          20, 50, 80, 25,
          hwnd, (HMENU) 1, NULL, NULL);

      CreateWindowW(L"button", L"Quit",
          WS_VISIBLE | WS_CHILD ,
          120, 50, 80, 25,
          hwnd, (HMENU) 2, NULL, NULL);
      break;

    case WM_COMMAND:

      if (LOWORD(wParam) == 1) {
        Beep(40, 50);
      }

      if (LOWORD(wParam) == 2) {
        PostQuitMessage(0);
      }

      break;

    case WM_DESTROY:

      PostQuitMessage(0);
      break;
  }

  return DefWindowProcW(hwnd, msg, wParam, lParam);
}
</pre>


<p>
In our example we have created two buttons. On button will beep. 
The other one will close the window. 
</p>

<pre class="explanation">
case WM_COMMAND:

  if (LOWORD(wParam) == 1) {
    Beep(40, 50);
  }

  if (LOWORD(wParam) == 2) {
    PostQuitMessage(0);
  }

  break;
</pre>

<p>
The control id is in the <code>LOWORD</code> of the <code>wParam</code>. 
Depending on the control id, we call the <code>Beep()</code> function or 
the <code>PostQuitMessage()</code> function. 
</p>

<img src="/img/gui/winapi/buttons.png" alt="Button controls">
<div class="figure">Button controls</div>


<h2>Check box</h2>

<p>
A check box control is a box that you can click to turn an option on or off. 
</p>

<pre class="code">
#include &lt;windows.h&gt;
#include &lt;stdbool.h&gt;

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);


int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PWSTR lpCmdLine, int nCmdShow)
{
  MSG  msg;    
  WNDCLASSW wc = {0};
  wc.lpszClassName = L"Check Box";
  wc.hInstance     = hInstance ;
  wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
  wc.lpfnWndProc   = WndProc;
  wc.hCursor       = LoadCursor(0, IDC_ARROW);

  RegisterClassW(&wc);
  CreateWindowW(wc.lpszClassName, L"Check Box",
                WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                150, 150, 230, 150, 0, 0, hInstance, 0);

  while( GetMessage(&msg, NULL, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }

  return (int) msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, 
    WPARAM wParam, LPARAM lParam)
{
  bool checked = true;

  switch(msg)  
  {
    case WM_CREATE:

      CreateWindowW(L"button", L"Show Title",
          WS_VISIBLE | WS_CHILD | BS_CHECKBOX,
          20, 20, 185, 35, hwnd, (HMENU) 1, 
          NULL, NULL);

      CheckDlgButton(hwnd, 1, BST_CHECKED);
      break;

    case WM_COMMAND:

      checked = IsDlgButtonChecked(hwnd, 1);

      if (checked) {

        CheckDlgButton(hwnd, 1, BST_UNCHECKED);
        SetWindowTextW(hwnd, L"");

      } else {

        CheckDlgButton(hwnd, 1, BST_CHECKED);
        SetWindowTextW(hwnd, L"Check Box");
      }
      break;

    case WM_DESTROY:

      PostQuitMessage(0);
      break;
  }

  return DefWindowProcW(hwnd, msg, wParam, lParam);
}	
</pre>

<p>
In our example, we show or hide the window title depending 
on the state of the check box. In Windows, check box is a special kind of a 
button. We create a check box, if we set a specific style to the button class. 
In our example, it is <code>BS_CHECKBOX</code>. 
</p>

<pre class="explanation">
checked = IsDlgButtonChecked(hwnd, 1);
</pre>

<p>
We determine the state of the check box using the <code>IsDlgButtonChecked()</code> 
function. 
</p>

<pre class="explanation">
CheckDlgButton(hwnd, 1, BST_UNCHECKED);
</pre>

<p>
We check and uncheck the check box using the <code>CheckDlgButton()</code> 
function.
</p>

<pre class="explanation">
SetWindowTextW(hwnd, L"");
</pre>

<p>
The <code>SetWindowTextW()</code> function sets the title of the window.
</p>

<img src="/img/gui/winapi/checkbox.png" alt="Checkbox control">
<div class="figure">Checkbox control</div>


<h2>Edit Control</h2>

<p>
Edit control is a rectangular child window. Edit control is used to enter 
and edit text. It can be single line or multiline. 
</p>

<pre class="code">
#include &lt;windows.h&gt;

#define ID_EDIT 1
#define ID_BUTTON 2

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PWSTR lpCmdLine, int nCmdShow )
{
  MSG  msg;    
  WNDCLASSW wc = {0};
  wc.lpszClassName = L"Edit Control";
  wc.hInstance     = hInstance;
  wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
  wc.lpfnWndProc   = WndProc;
  wc.hCursor       = LoadCursor(0,IDC_ARROW);

  RegisterClassW(&wc);
  CreateWindowW(wc.lpszClassName, L"Edit control",
                WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                220, 220, 280, 200, 0, 0, hInstance, 0);  

  while(GetMessage(&msg, NULL, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }

  return (int) msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, 
    WPARAM wParam, LPARAM lParam)
{
  static HWND hwndEdit;
  HWND hwndButton;

  switch(msg)
  {
    case WM_CREATE:

      hwndEdit = CreateWindowW(L"Edit", NULL, 
        WS_CHILD | WS_VISIBLE | WS_BORDER,
        50, 50, 150, 20, hwnd, (HMENU) ID_EDIT,
        NULL, NULL);

      hwndButton = CreateWindowW(L"button", L"Set Title",
        WS_VISIBLE | WS_CHILD, 50, 100, 80, 25,
        hwnd, (HMENU) ID_BUTTON, NULL, NULL);

      break;

    case WM_COMMAND:	

      if (HIWORD(wParam) == BN_CLICKED) {

         int len = GetWindowTextLengthW(hwndEdit) + 1;
         wchar_t text[len];

         GetWindowTextW(hwndEdit, text, len);
         SetWindowTextW(hwnd, text);
      }
      break;

      case WM_DESTROY:
        PostQuitMessage(0);
      break;
  }

  return DefWindowProcW(hwnd, msg, wParam, lParam);
}
</pre>

<p>
In our example, we have an edit control and a button. We can put some text 
into the edit control. If we click on the button, the entered text will
be displayed in the titlebar of the main window. 
</p>

<pre class="explanation">
if (HIWORD(wParam) == BN_CLICKED) {

   int len = GetWindowTextLengthW(hwndEdit) + 1;
   wchar_t text[len];

   GetWindowTextW(hwndEdit, text, len);
   SetWindowTextW(hwnd, text);
}
</pre>

<p>
The <code>GetWindowTextLengthW()</code> returns the text length entered. Notice, 
that we add 1 to the length. This is to include the zero terminator. Try to 
omit it and see what happens. The <code>GetWindowTextW()</code> receives the text 
from the edit control. We use hwndEdit as an id. The <code>SetWindowTextW()</code> 
sets the text for the window. In this context, it is a title of the main window.
</p>

<img src="/img/gui/winapi/edit.png" alt="Edit control">
<div class="figure">Figure: Edit control</div>

<p>
In this part of the Winapi tutorial, we have covered Windows controls. 
</p>

<div class="center"> 
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* horizontal */
google_ad_slot = "1734478269";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script> 
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> 
</script> 
</div> 
<br> 

<div class="botNav, center">
<span class="botNavItem"><a href="/">Home</a></span> ‡ <span class="botNavItem"><a href="..">Contents</a></span> ‡
<span class="botNavItem"><a href="#">Top of Page</a></span>
</div>


<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified September 24, 2012  <span class="copyright">&copy; 2007 - 2013 Jan Bodnar</span>
</div>
</div>

</div> <!-- content -->

</div> <!-- container -->

</body>
</html>

